
/**
** \file       ast_printer.c
**
** \brief      these functions handle the ast printer
**
** \author     Ben M'rad Hanna, Laterem Hamza, Boillot Ulysse, De Olivera
**             Guillaume and Nguyen Viet Dung
**
** \version    0.8
**
** \date       26 Novembre 2010
**
*/

#include "ast_printer.h"
#include "rules.h"
#include "../lexer/token.h"
#include "../exec_cmdline.h"

#include <stdio.h>

void		print_int(int	n,
			  int	fd)
{
  char		c;

  if ((n < 10) && (n >= 0))
    {
      c = n + '0';
      write(fd, &c, 1);
    }
  else
    {
      if (n < 0)
	{
	  write(fd, "-", 1);
	  print_int(-n, fd);
	}
      else
	{
	  print_int((n / 10), fd);
	  c = n % 10 + '0';
	  write(fd, &c, 1);
	}
    }
}

void		print_ast(s_ast		*ast)
{
  int		fd;
  int		i = 0;

  fd = open("ast.dot", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
  write(fd, "digraph \"42sh-ast\" {\n", 21);
  write(fd, "node [fontname=Vera, color=red1, style=filled];\n", 48);
  if (ast == NULL)
    write(fd, "0 [label = \"null\"];\n", 20);
  else
    {
      write(fd, "0 [label = \"ast\"];\n", 19);
      print_list(ast->list, i + 1, fd);
    }
  write(fd, "}", 1);
  close(fd);
}

void		print_list(s_list	*list,
			   int		i,
			   int		fd)
{
  if (list != NULL)
    {
      print_int(i, fd);
      write(fd, " [label = \"list\"];\n", 19);
      write(fd, "0 -> ", 5);
      print_int(i, fd);
      write(fd, "\n", 1);
      i = print_andor(list->andor, i, fd);
    }
  else
     {
       print_int(i, fd);
       write(fd, " [label = \"null\"];\n", 19);
       write(fd, "0 -> ", 5);
       print_int(i, fd);
       write(fd, "\n", 1);
     }
}

int		print_andor(s_andor	*node,
			    int		last,
			    int		fd)
{
  s_andor	*tmp = node;
  int		i = last;

  while (tmp != NULL)
    {
      ++last;
      print_int(last, fd);
      write(fd, " [label = \"andor\"];\n", 20);
      print_int(i, fd);
      write(fd, " -> ", 4);
      print_int(last, fd);
      write(fd, "\n", 1);
      last = print_pipeline(tmp->pl, last, fd, last);
      tmp = tmp->next;
    }
  return (last);
}

int		print_pipeline(s_pipeline	*node,
			       int		i,
			       int		fd,
			       int		last)
{
  s_pipeline	*tmp = node;

  while (tmp != NULL)
    {
      ++last;
      print_int(last, fd);
      write(fd, " [label = \"pipe\"];\n", 19);
      print_int(i, fd);
      write(fd, " -> ", 4);
      print_int(last, fd);
      write(fd, "\n", 1);
      if (tmp != NULL)
	last = print_cmd(tmp->cmd, last, fd, last);
      tmp = tmp->next;
    }
  return (last);
}
